/**
 * package class is from
 */
package Model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Ship class that player will use to traverse the universe, fight, and store goods.
 * @author Ben
 * @version 1
 */
public class Ship implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = -3393804700682380904L;

	/**
	 * characteristics of ships
	 */
	public int attackVal, speed, armor, 
		fuelCap, fuel, maxCargo, currCargo, health, maxHealth, type;

	/**
	 * characteristics compiled in Array list
	 */
	private final List<String> shipKeys;

	/**
	 * hash map of cargo
	 */
	public Map<String,TradeGood> cargo;

	/**
	 * string to represent name of ship
	 */
	public String shipType;
	
	/**
	 * Ship constructor that takes in an int value that represents a ship type. Ship will 
	 * then assign attributes based on the ship type inputed.
	 * @param type the number referring to a type of ship to construct
	 * Numbers listed in above comments.
	 */
	public Ship(int type){
		this.type = type;
		shipKeys = new ArrayList<String>();
		if (type == 1){
			attackVal = 7;
			speed = 3;
			armor = 1;
			fuelCap = 20;
			fuel = 20;
			maxCargo = 5;
			maxHealth = 5;
			health = 5;
			shipType = "FLEA";
		}
		if (type == 2){
			attackVal = 8;
			speed = 4;
			armor = 2;
			fuelCap = 14;
			fuel = 14;
			maxCargo = 15;
			maxHealth = 10;
			health = 10;
			shipType = "GNAT";	
		}
		if (type == 3){
			attackVal = 9;
			speed = 5;
			armor = 3;
			fuelCap = 17;
			fuel = 17;
			maxCargo = 20;
			maxHealth = 15;
			health = 15;
			shipType = "FIREFLY";
		}
		if (type == 4){
			shipType = "MOSQUITO";
			attackVal = 12;
			armor = 4;
			fuelCap = 13;
			fuel = 13;
			maxCargo = 15;
			maxHealth = 20;
			health = 20;
			speed = 6;
		}
		if (type == 5){
			shipType = "BUMBLEBEE";
			attackVal = 9;
			speed = 6;
			armor = 3;
			fuelCap = 15;
			fuel = 15;
			maxCargo = 20;
			maxHealth = 20;
			health = 20;
		}
		if (type == 6){
			shipType = "BEETLE";
			attackVal = 7;
			speed = 6;
			armor = 2;
			fuelCap = 14;
			fuel = 14;
			maxCargo = 50;
			maxHealth = 20;
			health = 20;
		}
		if (type == 7){
			shipType = "HORNET";
			attackVal = 17;
			speed = 8;
			armor = 4;
			fuelCap = 16;
			fuel = 16;
			maxCargo = 20;
			maxHealth = 20;
			health = 20;
		}
		if (type == 8){
			shipType = "GRASSHOPPER";
			attackVal = 14;
			speed = 8;
			armor = 4;
			fuelCap = 15;
			fuel = 15;
			maxCargo = 30;
			maxHealth = 20;
			health = 20;
		}
		if (type == 9){
			shipType = "Termite";
			attackVal = 9;
			speed = 7;
			armor = 6;
			fuelCap = 13;
			fuel = 13;
			maxCargo = 60;
			maxHealth = 25;
			health = 25;
		}
		else {
			shipType = "WASP";
			attackVal = 22;
			speed = 10;
			armor = 5;
			fuelCap = 14;
			maxCargo = 35;
			maxHealth = 20;
			health = 20;
			fuel = 14;
		}
		
		cargo = new HashMap<String,TradeGood>();
	}
	
	/**
	 * Returns the speed of a given ship.
	 * @return int value referring to speed
	 */
	public int getSpeed(){
		return speed;
	}
	
	/**
	 * Returns the attack value of a given ship.
	 * @return int value of attack
	 */
	public int getattack(){
		return attackVal;
	}
	
	/**
	 * Returns the armor value of a given ship.
	 * @return int value of the armor of the ship
	 */
	public int getarmor(){
		return armor;
	}
	
	/**
	 * Returns the health value of a given ship.
	 * @return the int value of the health of the ship
	 */
	public int gethealth(){
		return health;
	}
	
	/**
	 * Sets the health value of a given ship.
	 * @param health the new health value of the ship
	 */
	public void sethealth(int health){
		this.health = health;
	}
	
	/**
	 * Returns the fuel capacity of a given ship.
	 * @return the int value of the fuel capacity of the ship
	 */
	public int getFuelCap(){
		return fuelCap;
	}
	
	/**
	 *	Returns the amount of fuel in a given ship.
	 * @return int value of the amount of fuel in the ship
	 */
	public int getFuel(){
		return fuel;
	}
	
	/**
	 * Sets the fuel value in a given ship.
	 * @param fuel the new amount of fuel in the ship after warping
	 */
	public void setFuel(int fuel){
		this.fuel = fuel;
	}
	
	/**
	 * Returns the max health of a given ship.
	 * @return int value of max health of the ship
	 */
	public int getMaxHealth(){
		return maxHealth;
	}
	
	/**
	 * Returns the type of a ship.
	 * @return the string of the ship type
	 */
	public String getShipType(){
		return shipType;
	}
	
	 /**
	  * Gets the cargo capacity for a given ship.
	  * @return int value of the cargo capacity of the ship
	  */
	public int getMaxCargo(){
		return maxCargo;
	}
	
	/**
	 * Method to compare speeds between two inputed ships.
	 * It determines if a ship has the ability to run away.
	 * @param one the ship trying to run away
	 * @param two the ship trying to catch the ship
	 * @return an int value that returns the faster ship (1 for running) (2 for catching)
	 */
	public int compareSpeed(Ship one, Ship two){
		final int speedOne = one.getSpeed();
		final int speedTwo = two.getSpeed();
		if (speedOne > speedTwo){
			return 1;
		}
		if (speedOne < speedTwo){
			return -1;
		} else {
			return 0;
		}
	}
	
	/**
	 * Fight method to calculate conflict between two ships and determine winner.
	 * @param one the attacking ship
	 * @param two the defending ship
	 * @return and int representing whether the winning ship 
	 * was the attacking (1) or defending (2)
	 */
	public int fight(Ship one, Ship two){
		final int oneAttack = one.getattack();
		final int oneArmor = one.getarmor();
		int oneHealth = one.gethealth();
		final int twoAttack = two.getattack();
		final int twoArmor = two.getarmor();
		int twoHealth = two.gethealth();
		
		final int oneDamage = twoAttack - oneArmor;
		final int twoDamage = oneAttack - twoArmor;
		
		while (oneHealth > 0 || twoHealth > 0){
			oneHealth = oneHealth - oneDamage;
			twoHealth = twoHealth - twoDamage;
		}
		
		one.sethealth(oneHealth);
		two.sethealth(twoHealth);
		
		if (oneHealth > twoHealth){
			return 1;
		}
		if (oneHealth < twoHealth){
			return 2;
		} else { 
			return 1;
		}
	}
	
	/**
	 * Returns an array of the TradeGoods contained in the ship's cargo.
	 * @return TradeGood[] and array of TradeGoods contained in the ship's cargo
	 */
	public Map<String,TradeGood> getCargo(){
		return cargo;
	}
	
	/**
	 * Sets the number of cargo slots in the player's ship.
	 * @param num number of slots of cargo that are full
	 */
	public void setCurrCargo(int num){
		currCargo = num;
	}
	
	/**
	 * Gets the current number of slots filled in the cargo of the player's ship.
	 * @return current number of slots filled in the cargo of player's ship.
	 */
	public int getCurrCargo(){
		return currCargo;
	}
	
	/**
	 * Returns whether the cargo is full.
	 * @return boolean 
	 */
	public boolean isFull(){
		return (currCargo == maxCargo);
	}
	
	/**
	 * Sets the cargo being hold by the player.
	 * @param cargo the TradeGood array to replace the old array of tradeGoods
	 */
	public void setCargo(Map<String,TradeGood> cargo){
		this.cargo = cargo;
	}
	
	/**
	 * getter for ship keys
	 * @return ship keys
	 */
	public List<String> getShipKeys(){
		return shipKeys;
	}
	
	/**
	 * @return the name of the ship
	 */
	public String toString(){
		return shipType;
	}
}
